package io.itit.ecp.admin.provide.action.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import icu.mhb.mybatisplus.plugln.extend.Joins;
import io.itit.ecp.admin.provide.action.req.DeviceWarningQueryReq;
import io.itit.ecp.admin.provide.action.req.DeviceWarningReq;
import io.itit.ecp.admin.provide.action.resp.DeviceWarningResp;
import io.itit.ecp.admin.provide.action.resp.DeviceWarningThresholdResp;
import io.itit.ecp.admin.provide.action.resp.DeviceWarningUserResp;
import io.itit.ecp.admin.provide.helper.SceneHelper;
import io.itit.ecp.admin.server.entity.*;
import io.itit.ecp.admin.server.service.*;
import io.itit.grass.common.provide.action.req.BaseBatchIdReq;
import io.itit.grass.common.provide.action.req.BaseIdReq;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.itit.grass.common.provide.action.validation.IAdd;
import io.itit.grass.common.provide.action.validation.IQueryPage;
import io.itit.grass.common.provide.action.validation.IRequired;
import io.itit.grass.common.provide.action.validation.IUpdate;
import io.itit.grass.common.server.entity.BaseEntity;
import io.itit.grass.common.server.utils.ConvertUtils;
import io.itit.grass.core.server.service.IUserService;
import io.itit.grass.web.wall.utils.PageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * @Author：Roy
 * @Description：设备管理-预警设置
 * @Date：Create by 2023-12-04 15:28:53
 */
@Api(tags = "设备管理-预警设置")
@RestController
@RequestMapping("/ecp-admin/deviceWarning")
public class DeviceWarningController {

    @Resource
    private IDeviceWarningService deviceWarningService;

    @Resource
    private IDeviceWarningUserService deviceWarningUserService;

    @Resource
    private IDeviceWarningThresholdService deviceWarningThresholdService;

    @Resource
    private IDeviceService deviceService;

    @Resource
    private IUserService userService;

    @Resource
    private IPhysicalModelService physicalModelService;

    @ApiOperation("分页查询")
    @PostMapping("queryPage")
    @RequiresPermissions("ecp-admin:deviceWarning:search")
    public ResultResp<IPage<DeviceWarningResp>> queryPage(@RequestBody @Validated(IQueryPage.class) DeviceWarningQueryReq req) {
        Page<DeviceWarningResp> page = buildQW(req).joinPage(PageUtils.getPage(req, DeviceWarningResp.class), DeviceWarningResp.class);
        return ResultResp.success(SceneHelper.i().setSceneInfo(page));
    }

    @ApiOperation("详情")
    @PostMapping("detail")
    @RequiresPermissions("ecp-admin:deviceWarning:search")
    public ResultResp<DeviceWarningResp> detail(@RequestBody @Validated(IRequired.class) BaseIdReq req) {
        DeviceWarningResp deviceWarningResp = ConvertUtils.copy(deviceWarningService.getById(req.getId()), DeviceWarningResp.class);
        Set<String> userIds = deviceWarningUserService.findByDeviceWarningId(req.getId()).stream()
                .map(DeviceWarningUserEntity::getUserId).collect(Collectors.toSet());
        List<DeviceWarningUserResp> userResps = userIds.isEmpty() ? Collections.emptyList() : userService.listByIds(userIds).stream().map(item -> {
            DeviceWarningUserResp userResp = new DeviceWarningUserResp();
            userResp.setId(item.getId());
            userResp.setUserName(item.getUserName());
            return userResp;
        }).collect(Collectors.toList());
        deviceWarningResp.setWarningUsers(userResps);
        List<DeviceWarningThresholdEntity> thresholdEntities = deviceWarningThresholdService.findByDeviceWarningId(req.getId());
        Set<String> deviceIds = thresholdEntities.stream().map(DeviceWarningThresholdEntity::getDeviceId).collect(Collectors.toSet());
        Map<String, DeviceEntity> deviceEntityMap = deviceIds.isEmpty() ? Collections.emptyMap() : deviceService.listByIds(deviceIds)
                .stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));
        Set<String> modelIds = thresholdEntities.stream().map(DeviceWarningThresholdEntity::getModelId).collect(Collectors.toSet());
        Map<String, PhysicalModelEntity> modelMap = modelIds.isEmpty() ? Collections.emptyMap() : physicalModelService.listByIds(modelIds)
                .stream().collect(Collectors.toMap(BaseEntity::getId, Function.identity()));
        deviceWarningResp.setWarningThresholds(thresholdEntities
                .stream().map(item -> {
                    DeviceWarningThresholdResp thresholdResp = new DeviceWarningThresholdResp();
                    thresholdResp.setId(item.getId());
                    DeviceEntity deviceEntity = deviceEntityMap.get(item.getDeviceId());
                    PhysicalModelEntity physicalModel = modelMap.get(item.getModelId());
                    return thresholdResp.setDeviceWarningId(item.getDeviceWarningId())
                            .setJudgeRule(item.getJudgeRule())
                            .setDeviceId(item.getDeviceId())
                            .setDeviceName(Objects.isNull(deviceEntity) ? null : deviceEntity.getDeviceName())
                            .setModelId(item.getModelId())
                            .setModelName(Objects.isNull(physicalModel) ? null : physicalModel.getModelName())
                            .setThresholdValue(item.getThresholdValue());
                }).collect(Collectors.toList()));
        return ResultResp.success(deviceWarningResp);
    }

    /**
     * 组装查询条件
     *
     * @param req
     * @return
     */
    private static JoinLambdaWrapper<DeviceWarningEntity> buildQW(DeviceWarningQueryReq req) {
        return Joins.of(DeviceWarningEntity.class)
                .leftJoin(SceneProjectEntity.class, SceneProjectEntity::getId, DeviceWarningEntity::getSceneProjectId)
                .select(SceneProjectEntity::getProjectName)
                .end()
                .like(StringUtils.isNotEmpty(req.getWarningName()), DeviceWarningEntity::getWarningName, req.getWarningName())
                .eq(StringUtils.isNotEmpty(req.getSceneProjectId()), DeviceWarningEntity::getSceneProjectId, req.getSceneProjectId())
                .eq(StringUtils.isNotEmpty(req.getSceneEdificeId()), DeviceWarningEntity::getSceneEdificeId, req.getSceneEdificeId())
                .eq(StringUtils.isNotEmpty(req.getSceneFloorId()), DeviceWarningEntity::getSceneFloorId, req.getSceneFloorId())
                .eq(StringUtils.isNotEmpty(req.getSceneRoomId()), DeviceWarningEntity::getSceneRoomId, req.getSceneRoomId())
                .in(CollectionUtils.isNotEmpty(req.getIds()), DeviceWarningEntity::getId, req.getIds())
                .last(StringUtils.isNotEmpty(req.getSortColumn()), PageUtils.lastOrderBy(req))
                .orderByDesc(StringUtils.isEmpty(req.getSortColumn()), DeviceWarningEntity::getCreateTm);
    }

    @ApiOperation("新增")
    @PostMapping("add")
    @RequiresPermissions("ecp-admin:deviceWarning:add")
    public ResultResp<Boolean> add(@RequestBody @Validated({IAdd.class}) DeviceWarningReq req) {
        boolean res = deviceWarningService.saveOrUpdateDeviceWarning(ConvertUtils.convertIgnoreId(req, DeviceWarningEntity.class), req.getUserIds(), req.getWarningJson());
        return ResultResp.success(res);
    }

    @ApiOperation("编辑")
    @PostMapping("update")
    @RequiresPermissions("ecp-admin:deviceWarning:update")
    public ResultResp<Boolean> update(@RequestBody @Validated({IUpdate.class}) DeviceWarningReq req) {
        boolean res = deviceWarningService.saveOrUpdateDeviceWarning(ConvertUtils.copy(req, DeviceWarningEntity.class), req.getUserIds(), req.getWarningJson());
        return ResultResp.success(res);
    }

    @ApiOperation("删除(根据Id删)")
    @PostMapping("deleteById")
    @RequiresPermissions("ecp-admin:deviceWarning:deleteById")
    public ResultResp<Boolean> deleteById(@RequestBody @Validated({IRequired.class}) BaseIdReq req) {
        return ResultResp.success(deviceWarningService.removeById(req.getId()));
    }

    @ApiOperation("批量删除")
    @PostMapping("batchDelete")
    @RequiresPermissions("ecp-admin:deviceWarning:batchDelete")
    public ResultResp<Boolean> batchDelete(@RequestBody @Validated({IRequired.class}) BaseBatchIdReq req) {
        return ResultResp.success(deviceWarningService.removeBatchByIds(req.getIds(), 1000));
    }
}
